package com.start.pay.core;

import com.start.common.entity.StartDicData;
import com.start.common.exceptions.StartBusException;
import com.start.common.tools.SpringContextTools;
import com.start.pay.core.entity.StartPlatformPlayConfig;
import com.start.pay.core.interfaces.StartBasePayPlatform;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class StartPayPlatformManager {
    private ConcurrentHashMap<String, StartBasePayPlatform> map = new ConcurrentHashMap<>();

    private static final StartPayPlatformManager manager = new StartPayPlatformManager();

    private boolean isInit = false;


    public static StartPayPlatformManager getInstance() {
        if (manager.isInit){
            return manager;
        }

        synchronized (StartPayServerService.class) {
            if (manager.isInit) {
                return manager;
            }
            manager.init();
            manager.isInit = true;
            return manager;
        }
    }

    private void init() {
        Map<String, StartBasePayPlatform> beans = SpringContextTools.getBeans(StartBasePayPlatform.class, false);
        if (beans == null || beans.isEmpty()) return;
        for (StartBasePayPlatform platform : beans.values()) {
            String platformType = platform.getPlatformType();
            if (StringUtils.isEmpty(platformType)) {
                log.error(platform.getClass().getName() + " 未指定平台类型。");
                continue;
            }
            if (map.containsKey(platformType)) {
                log.error("找到多个相同平台处理实例：" + platformType + "\n" + map.get(platformType).getClass() + "," + platform.getClass());
                continue;
            }
            map.put(platformType, platform);
        }
    }

    public StartBasePayPlatform getPlatform(String platformType) {
        if (!map.containsKey(platformType)) {
            log.error("平台类型：" + platformType + "的相关配置不存在");
            throw new StartBusException("获取支付平台配置失败");
        }
        return map.get(platformType);
    }

    public void addPayPlatform(StartBasePayPlatform platform) {
        if (StringUtils.isEmpty(platform.getPlatformType())) {
            throw new RuntimeException("支付平台配置不能为空");
        }
        map.put(platform.getPlatformType(), platform);
    }

    public void addPayPlatformConfig(String platform, String appId, StartPlatformPlayConfig config) {
        StartBasePayPlatform startBasePayPlatform = map.get(platform);
        Class configClazz = startBasePayPlatform.getConfigClazz();
        if (!configClazz.isInstance(config)) {
            log.error("配置与所需配置类型不一致，需要:" + configClazz.getName());
            throw new RuntimeException("配置与所需配置类型不一致，需要:" + configClazz.getName());
        }
        startBasePayPlatform.addPlayConfig(config);
    }

    public List<StartDicData> getAllPayPlatformType() {
        Collection<StartBasePayPlatform> values = map.values();
        List<StartDicData> result = new ArrayList<>();
        for (StartBasePayPlatform v : values) {
            result.add(new StartDicData(StringUtils.isNotEmpty(v.getPlatformTypeLabel()) ? v.getPlatformTypeLabel() : v.getPlatformType(), v.getPlatformType()));
        }

        return result;
    }

    public boolean hasPlatform(String platformType, String appId) {
        if (!map.containsKey(platformType)) {
            return false;
        }
        if (StringUtils.isAllBlank(appId)) {
            return true;
        }
        StartBasePayPlatform platform = getPlatform(platformType);
        return platform.hasAppId(appId);
    }

    public void remove(String platformType, String appId) {
        StartBasePayPlatform platform = getPlatform(platformType);
        platform.removeByAppId(appId);
    }
}
